package com.edu.model.tree.v1;

import com.edu.model.tree.Node;

import java.lang.reflect.Field;
import java.util.List;

public class ConvertTree<T> {

    /**
     * 根节点数据
     */
    private T root;
    /**
     * 节点树
     */
    private TreeNode<T> tree;

    public T getRoot() {
        return root;
    }

    /**
     * 获取节点树
     *
     * @return
     */
    private TreeNode<T> getTree() {
        return tree;
    }

    /**
     * 添加节点到节点树
     *
     * @param data    节点
     * @param idName  节点id名称
     * @param fIdName 父节点id名称
     */
    public void put(T data, String idName, String fIdName) {
        if (root == null) {
            root = data;
            tree = new TreeNode<>(data);
        } else {
            String fieldValue = getFieldValue(data, fIdName);
            String rootFiledValue = getFieldValue(root, idName);
            if (rootFiledValue.equals(fieldValue)) {
                List<TreeNode<T>> childrenNode = tree.getChildrenNode();
                childrenNode.add(new TreeNode<T>(data));
            } else {
                put(data, idName, fIdName, tree.getChildrenNode());
            }
        }
    }

    /**
     * 添加节点到节点树
     *
     * @param data         节点
     * @param idName       节点id名称
     * @param fIdName      父节点id名称
     * @param childrenNode 子节点集合
     */
    private void put(T data, String idName, String fIdName, List<TreeNode<T>> childrenNode) {
        if (childrenNode == null || childrenNode.isEmpty()) {
            return;
        } else {
            for (TreeNode<T> tTreeNode : childrenNode) {
                String fieldValue = getFieldValue(data, fIdName);
                String rootFiledValue = getFieldValue(tTreeNode.getData(), idName);
                if (rootFiledValue.equals(fieldValue)) {
                    List<TreeNode<T>> children = tTreeNode.getChildrenNode();
                    children.add(new TreeNode<T>(data));
                    return;
                } else {
                    List<TreeNode<T>> children = tTreeNode.getChildrenNode();
                    put(data, idName, fIdName, children);
                }
            }
        }
    }

    /**
     * 查找父节点
     *
     * @param t
     * @param idName
     * @param fIdName
     * @return
     */
    public T find(T t, String idName, String fIdName) {
        T data = tree.getData();
        String fieldValue = getFieldValue(data, idName);
        String value = getFieldValue(t, fIdName);
        if (value.equals(fieldValue)) {
            return data;
        }
        return find(t, idName, fIdName, tree.getChildrenNode());
    }

    /**
     * 查找父节点
     *
     * @param t
     * @param idName
     * @param fIdName
     * @param childrenNode
     * @return
     */
    public T find(T t, String idName, String fIdName, List<TreeNode<T>> childrenNode) {
        if (childrenNode.isEmpty()) {
            return null;
        }
        T tem = null;
        for (TreeNode<T> tTreeNode : childrenNode) {
            if (tem != null) {
                break;
            }
            T data = tTreeNode.getData();
            String fieldValue = getFieldValue(data, idName);
            String value = getFieldValue(t, fIdName);
            if (value.equals(fieldValue)) {
                return data;
            } else {
                tem = find(t, idName, fIdName, tTreeNode.getChildrenNode());
            }
        }
        return tem;
    }

    /**
     * 获取字段值
     *
     * @param o         class
     * @param fieldName 字段名
     * @return String
     */
    public String getFieldValue(T o, String fieldName) {
        //得到class
        Class cls = o.getClass();
        //得到所有属性
        Field field = null;
        try {
            field = getFieldByFieldName(cls,fieldName);
        } catch (NoSuchFieldException e) {
            try {
                field = cls.getSuperclass().getDeclaredField(fieldName);
            } catch (NoSuchFieldException ex) {
                throw new RuntimeException("获取属性值失败");
            }
        }
        try {
            //打开私有访问
            field.setAccessible(true);
            //获取属性
            Object result = field.get(o);
            if (result == null) {
                return null;
            }
            return result.toString();
        } catch (IllegalAccessException e) {
            throw new RuntimeException("获取属性值失败");
        }
    }

    public Field getFieldByFieldName(Class<?> clazz, String fieldName) throws NoSuchFieldException {
        for (; !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
            try {
                return clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
            }
        }

        throw new NoSuchFieldException();
    }


    public static void main(String[] args) {
        ConvertTree<Node> convertTree = new ConvertTree<>();
    }
}
